home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / clang / cslib15b.zip / DEMO / ADDRESS / CSADDIO.CPP < prev    next >
C/C++ Source or Header  |  1994-12-20  |  20KB  |  656 lines

  1. #include "csaddio.h"
  2.  
  3. extern unsigned _stklen=7000;  //A large stack is needed
  4.  
  5. ////////////// The used .def file is included as comment ////////
  6. /*
  7. class: NAM_foundation
  8. record: record
  9. file: csadr.dbf
  10. field: name s 40 T
  11. field: adre s 32
  12. field: city s 23 Y
  13. field: count s 32
  14. field: zip s 9
  15. field: tel s 17
  16. field: update d MDY2
  17. field: birth d DMY4 Y
  18. field: relation s 10 Y
  19. field: info s 70
  20. */
  21. /////////////// End of .def file //////////////////////////////////////////////
  22.  
  23. ///////////////////////////////// Constructor ////////////////////////////////
  24. NAM_foundation::NAM_foundation(void) 
  25.     is_open=FALSE; 
  26.     current=1; 
  27.     _update.format(MDY2); 
  28.     _birth.format(DMY4); 
  29. }
  30.  
  31. ///////////////////////////////// reindex ////////////////////////////////////
  32. void NAM_foundation::reindex(void) 
  33. {
  34.     U32 l=current;  
  35.     record *rp;  
  36.     in1.empty(); 
  37.     in2.empty(); 
  38.     in3.empty(); 
  39.     in4.empty(); 
  40.     for(current=numrec(); current>0; current--)  
  41.     {                          
  42.        rp=(record *)db.locate_rec(current);  
  43.        tokenize(rp->_name,&NAM_foundation::in1_ins_tok); 
  44.        in2.insert(rp->_city,¤t); 
  45.        in3.insert(&rp->__birth,¤t); 
  46.        in4.insert(rp->_relation,¤t); 
  47.     }                          
  48.     current=l;                 
  49. }
  50.  
  51. /////////////// append blank//////////////////////////////////////
  52. void NAM_foundation::append_blank(void) 
  53. {
  54.        append();
  55.        tokenize(recp->_name,&NAM_foundation::in1_ins_tok); 
  56.        in2.insert(rec._city,¤t); 
  57.        in3.insert(&rec.__birth,¤t); 
  58.        in4.insert(rec._relation,¤t); 
  59. }
  60.  
  61. ///////////////////////////////// append /////////////////////////////////////
  62. // This function doesn't update the indexes, which can save some 
  63. // disk I/O because you are likely to alter the fields 
  64. // immediatly after you have appended the record.
  65. // However, if you have an index on a field you don't update, this 
  66. // record will NOT appear in that particularly index! 
  67. // The 'append_blank' function does update all indexes, which 
  68. // makes it a safer, but slower option. 
  69. //  
  70. void NAM_foundation::append(void) 
  71. {
  72.     write_rec();
  73.     memset(&rec,0,sizeof(record)); 
  74.     current=db.append_rec(&rec); 
  75.     recp=(record *)db.locate_rec(current); 
  76.     dirty=TRUE;    
  77.     _update.sem_jul(0L);
  78.     _birth.sem_jul(0L);
  79. }
  80.  
  81. ///////////////////////////////// open ///////////////////////////////////////
  82. void NAM_foundation::open(void) 
  83. {
  84.      if(is_open) return; 
  85.      int needs_reindex=FALSE;        
  86.      dirty=FALSE;        
  87.  
  88. #ifdef _Windows
  89.      int fre=300/9; //Use 300 kB for buffers. You may increase this.
  90. #else
  91.      int fre=(int)(coreleft()-100000L)/9/1024;
  92.      fre=max(fre,0); 
  93. #endif
  94.  
  95.      if(!db.open("csadr.dbf",fre)) 
  96.      {
  97.          csmess_disp("FATAL: Can't open database csadr.dbf.");
  98.          exit(1);
  99.      }
  100.      if(db.lengthrec()!=sizeof(record)) 
  101.      {
  102.          csmess_disp("FATAL: wrong record size.\n\rProbably wrong or old database file.");
  103.          db.close(); 
  104.          exit(1); 
  105.      }
  106.      if(!file_exist("csadr01.idx"))
  107.      { 
  108.        in1.multiple_keys(TRUE);
  109.        in1.define("csadr01.idx",NAME_LENGTH+1,sizeof(long));
  110.        needs_reindex=TRUE; 
  111.      } 
  112.      in1.open("csadr01.idx",fre*2);
  113.   
  114.      if(!file_exist("csadr02.idx"))
  115.      { 
  116.        in2.multiple_keys(TRUE);
  117.        in2.define("csadr02.idx",CITY_LENGTH+1,sizeof(long));
  118.        needs_reindex=TRUE; 
  119.      } 
  120.      in2.open("csadr02.idx",fre*2);
  121.   
  122.      if(!file_exist("csadr03.idx"))
  123.      { 
  124.        in3.multiple_keys(TRUE);
  125.        in3.define("csadr03.idx",sizeof(long),sizeof(long));
  126.        needs_reindex=TRUE; 
  127.      } 
  128.      in3.open("csadr03.idx",fre*2);
  129.   
  130.      if(!file_exist("csadr04.idx"))
  131.      { 
  132.        in4.multiple_keys(TRUE);
  133.        in4.define("csadr04.idx",RELATION_LENGTH+1,sizeof(long));
  134.        needs_reindex=TRUE; 
  135.      } 
  136.      in4.open("csadr04.idx",fre*2);
  137.   
  138.      if(needs_reindex) reindex(); 
  139.      is_open=TRUE; 
  140.      if(numrec()==0) append_blank();
  141.      else            read_rec(); 
  142.   
  143.      order(UNSORTED);  
  144. }
  145.  
  146. ///////////////////////////////// close //////////////////////////////////////
  147. void NAM_foundation::close(void) 
  148. {
  149.      if(!is_open) return; 
  150.      write_rec(); 
  151.      db.close(); 
  152.      in1.close();
  153.      in2.close();
  154.      in3.close();
  155.      in4.close();
  156.      is_open=FALSE; 
  157. }
  158.  
  159. ///////////////////////////////// define /////////////////////////////////////
  160. void NAM_foundation::define(void) 
  161. {
  162.      db.define("csadr.dbf",sizeof(record)); 
  163.      in1.multiple_keys(TRUE);
  164.      in1.define("csadr01.idx",NAME_LENGTH+1,sizeof(long));
  165.      in2.multiple_keys(TRUE);
  166.      in2.define("csadr02.idx",CITY_LENGTH+1,sizeof(long));
  167.      in3.multiple_keys(TRUE);
  168.      in3.define("csadr03.idx",sizeof(long),sizeof(long));
  169.      in4.multiple_keys(TRUE);
  170.      in4.define("csadr04.idx",RELATION_LENGTH+1,sizeof(long));
  171. }
  172.  
  173. ///////////////////////////////// pack ///////////////////////////////////////
  174. void NAM_foundation::pack(void) 
  175. {
  176.      write_rec(); 
  177.      db.pack();
  178.      reindex();
  179.      if(numrec()==0) append_blank();
  180.      top();
  181. }
  182.  
  183. ///////////////////////////////// skip ///////////////////////////////////////
  184. int  NAM_foundation::skip(int delta) 
  185. {
  186.      long tmp_curr=curr_rec(); 
  187.      write_rec(); 
  188.      (this->*skip_fun)(delta); 
  189.      read_rec(); 
  190.      return (int)(curr_rec()-tmp_curr); 
  191. }
  192.  
  193. ///////////////////////////////// order //////////////////////////////////////
  194. void NAM_foundation::order(int nr) 
  195. {
  196.      switch(nr)
  197.      {
  198.          case 0:        //Unsorted 
  199.                   skip_fun  =&NAM_foundation::skip0;
  200.                   top_fun   =&NAM_foundation::top0;
  201.                   bottom_fun=&NAM_foundation::bottom0;
  202.                   search_fun=&NAM_foundation::search0;
  203.                   break; 
  204.          case 1:        //Index on field name
  205.                   skip_fun  =&NAM_foundation::skip1;
  206.                   top_fun   =&NAM_foundation::top1;
  207.                   bottom_fun=&NAM_foundation::bottom1;
  208.                   search_fun=&NAM_foundation::search1;
  209.                   break; 
  210.          case 2:        //Index on field city
  211.                   skip_fun  =&NAM_foundation::skip2;
  212.                   top_fun   =&NAM_foundation::top2;
  213.                   bottom_fun=&NAM_foundation::bottom2;
  214.                   search_fun=&NAM_foundation::search2;
  215.                   break; 
  216.          case 3:        //Index on field birth
  217.                   skip_fun  =&NAM_foundation::skip3;
  218.                   top_fun   =&NAM_foundation::top3;
  219.                   bottom_fun=&NAM_foundation::bottom3;
  220.                   search_fun=&NAM_foundation::search3;
  221.                   break; 
  222.          case 4:        //Index on field relation
  223.                   skip_fun  =&NAM_foundation::skip4;
  224.                   top_fun   =&NAM_foundation::top4;
  225.                   bottom_fun=&NAM_foundation::bottom4;
  226.                   search_fun=&NAM_foundation::search4;
  227.                   break; 
  228.      }
  229.      top();
  230. }
  231. /////////////////////////////writing record  ///////////////////////////////
  232. void NAM_foundation::write_rec2(void) 
  233. {
  234.     if(strcmp(recp->_name,rec._name)) 
  235.     { 
  236.       tokenize(recp->_name,&NAM_foundation::in1_del_tok); 
  237.       tokenize(rec._name,&NAM_foundation::in1_ins_tok); 
  238.     } 
  239.     if(strcmp(recp->_city,rec._city)) 
  240.     { 
  241.       in2.delet(recp->_city,¤t); 
  242.       in2.insert(rec._city,¤t); 
  243.     } 
  244.     rec.__update=_update.sem_jul(); 
  245.     rec.__birth=_birth.sem_jul(); 
  246.     if(recp->__birth!=rec.__birth) 
  247.     { 
  248.       in3.delet(&recp->__birth,¤t); 
  249.       in3.insert(&rec.__birth,¤t); 
  250.     } 
  251.     if(strcmp(recp->_relation,rec._relation)) 
  252.     { 
  253.       in4.delet(recp->_relation,¤t); 
  254.       in4.insert(rec._relation,¤t); 
  255.     } 
  256.     db.write_rec(current,&rec); 
  257.     dirty=FALSE;   
  258. }
  259.  
  260. ///////////////////////////////// export /////////////////////////////////////
  261. int  NAM_foundation::export(char *s) 
  262. {
  263.      FILE *fo=fopen(s,"w"); 
  264.      if(fo==NULL) return FALSE; 
  265.  
  266.      write_rec();
  267.      fprintf(fo,"class:  NAM_foundation");
  268.      fprintf(fo,"\nrecord: record");
  269.      fprintf(fo,"\nfile:   csadr.dbf");
  270.      fprintf(fo,"\nfield:  name s 40 Y");
  271.      fprintf(fo,"\nfield:  adre s 32  ");
  272.      fprintf(fo,"\nfield:  city s 23 Y");
  273.      fprintf(fo,"\nfield:  count s 32  ");
  274.      fprintf(fo,"\nfield:  zip s 9  ");
  275.      fprintf(fo,"\nfield:  tel s 17  ");
  276.      fprintf(fo,"\nfield:  update d  ");
  277.      fprintf(fo,"\nfield:  birth d Y");
  278.      fprintf(fo,"\nfield:  relation s 10 Y");
  279.      fprintf(fo,"\nfield:  info s 70  ");
  280.  
  281.      if(ferror(fo)) { fclose(fo); return FALSE; } 
  282.  
  283.      record *recp;
  284.      DATE conv;
  285.      conv.format(Y4MD);
  286.      for(long l=numrec();l>0;l--) 
  287.      {
  288.         recp=( record * )db.locate_rec(l);
  289.         fprintf(fo,"\n%c",12);
  290.         fprintf(fo,"\n%s",recp->_name);
  291.         fprintf(fo,"\n%s",recp->_adre);
  292.         fprintf(fo,"\n%s",recp->_city);
  293.         fprintf(fo,"\n%s",recp->_count);
  294.         fprintf(fo,"\n%s",recp->_zip);
  295.         fprintf(fo,"\n%s",recp->_tel);
  296.         conv.sem_jul(recp->__update);
  297.         fprintf(fo,"\n%s",(char *)conv);
  298.         conv.sem_jul(recp->__birth);
  299.         fprintf(fo,"\n%s",(char *)conv);
  300.         fprintf(fo,"\n%s",recp->_relation);
  301.         fprintf(fo,"\n%s",recp->_info);
  302.         fprintf(fo,"\n"); //Additional linefeed, to avoid trouble!
  303.  
  304.         if(ferror(fo)) { fclose(fo); return FALSE; } 
  305.      }
  306.      return !fclose(fo);  
  307. }
  308.  
  309. ///////////////////////////////// import /////////////////////////////////////
  310. int NAM_foundation::import(char *s) 
  311. {   
  312.  
  313.       FILE *fr=fopen(s,"r"); 
  314.       if(fr==NULL) return FALSE;
  315.   
  316.   
  317. #define MAX_NUM_FIELDS  100   //Increase this to allow more fields    
  318. #define MAX_FIELD_LEN   500   //Increase this to allow longer fields  
  319.  
  320.       int *finu;
  321.       finu=(int *)malloc(MAX_NUM_FIELDS*sizeof(int));
  322.       if(finu==NULL) { fclose(fr); return FALSE; }   
  323.  
  324.       char *fibu;    
  325.       fibu=(char *)malloc(MAX_FIELD_LEN);
  326.       if(fibu==NULL) { fclose(fr); free(finu); return FALSE; } 
  327.       *fibu=0;  
  328.  
  329.       char *fipo=fibu+strlen("field:");  
  330.       char *cp; 
  331.       int  ifieldnr=0;    
  332.       int  ofieldnr; 
  333.       DATE conv;
  334.       conv.format(Y4MD);
  335.  
  336.       memset(finu,0,MAX_NUM_FIELDS*sizeof(int));
  337.  
  338.       fgets(fibu,MAX_FIELD_LEN,fr); 
  339.       while(!strchr(fibu,12))  
  340.       {    
  341.         strlwr(fibu);
  342.         notabs(fibu);
  343.         trim_string(fibu);
  344.         if(strstr(fibu,"field:"))   
  345.         {  
  346.            ifieldnr++;  
  347.            trim_string(fipo);    
  348.            if((cp=strchr(fipo,' '))!=NULL) *cp=0;
  349.            if     (!strcmp(fipo,"name"))    ofieldnr=1;
  350.            else if(!strcmp(fipo,"adre"))    ofieldnr=2;
  351.            else if(!strcmp(fipo,"city"))    ofieldnr=3;
  352.            else if(!strcmp(fipo,"count"))    ofieldnr=4;
  353.            else if(!strcmp(fipo,"zip"))    ofieldnr=5;
  354.            else if(!strcmp(fipo,"tel"))    ofieldnr=6;
  355.            else if(!strcmp(fipo,"update"))    ofieldnr=7;
  356.            else if(!strcmp(fipo,"birth"))    ofieldnr=8;
  357.            else if(!strcmp(fipo,"relation"))    ofieldnr=9;
  358.            else if(!strcmp(fipo,"info"))    ofieldnr=10;
  359.            else ofieldnr=0; 
  360.            finu[ifieldnr]=ofieldnr; 
  361.         }  
  362.         fgets(fibu,MAX_FIELD_LEN,fr);    
  363.       }    
  364.  
  365.  
  366.  
  367.       for(;;)   
  368.       {    
  369.         if(!strchr(fibu,12))   
  370.         {  
  371.            ifieldnr++; 
  372.            if(ifieldnr<MAX_NUM_FIELDS) 
  373.              switch(finu[ifieldnr])   
  374.              {  
  375.                 case 0:  break;
  376.                 case 1:
  377.                          fibu[NAME_LENGTH]=0;
  378.                          name(fibu);
  379.                          break;
  380.                 case 2:
  381.                          fibu[ADRE_LENGTH]=0;
  382.                          adre(fibu);
  383.                          break;
  384.                 case 3:
  385.                          fibu[CITY_LENGTH]=0;
  386.                          city(fibu);
  387.                          break;
  388.                 case 4:
  389.                          fibu[COUNT_LENGTH]=0;
  390.                          count(fibu);
  391.                          break;
  392.                 case 5:
  393.                          fibu[ZIP_LENGTH]=0;
  394.                          zip(fibu);
  395.                          break;
  396.                 case 6:
  397.                          fibu[TEL_LENGTH]=0;
  398.                          tel(fibu);
  399.                          break;
  400.                 case 7:
  401.                          conv=fibu;
  402.                          _update.sem_jul(conv.sem_jul());
  403.                          break;
  404.                 case 8:
  405.                          conv=fibu;
  406.                          _birth.sem_jul(conv.sem_jul());
  407.                          break;
  408.                 case 9:
  409.                          fibu[RELATION_LENGTH]=0;
  410.                          relation(fibu);
  411.                          break;
  412.                 case 10:
  413.                          fibu[INFO_LENGTH]=0;
  414.                          info(fibu);
  415.                          break;
  416.              }  
  417.         }  
  418.         else    
  419.         {  
  420.            ifieldnr=0; 
  421.            append_blank();
  422.         }  
  423.         if(feof(fr)) break;    
  424.         fgets(fibu,MAX_FIELD_LEN,fr);    
  425.         cp=fibu+(max(1,strlen(fibu))-1); 
  426.         if(*cp=='\n') *cp=0;  //removing the line feed 
  427.       }    
  428.  
  429.  
  430.       fclose(fr); 
  431.       free(fibu); 
  432.       free(finu); 
  433.  
  434. #undef MAX_NUM_FIELDS
  435. #undef MAX_FIELD_LEN 
  436.  
  437.  return TRUE; 
  438. }
  439.  
  440. ///////////////////////////////// export to dBASE compatible file. ///////////
  441. int NAM_foundation::to_DBASE(char *s) 
  442. {   
  443.  
  444.       char bufje[12];
  445.       if(!is_open) return FALSE;
  446.  
  447.       write_rec(); 
  448.       FILE *fo=fopen(s,"wb"); 
  449.       if(fo==NULL) return FALSE;
  450.   
  451.       int i;
  452.   
  453.       DATE d_upda;
  454.       d_upda.sem_jul(db.sj_updated());
  455.       fputc(03,fo);  
  456.       
  457.       fputc(d_upda.year()%100,fo);  
  458.       fputc(d_upda.month(),fo);  
  459.       fputc(d_upda.day(),fo);  
  460.  
  461.       long nr_record=numrec(); 
  462.       fwrite(&nr_record,sizeof(long),1,fo); 
  463.       putw(354,fo);        //Header length 
  464.       putw(250,fo);        //Length of data record 
  465.       for(i=0;i<20;i++) fputc(0,fo); // 20 dummy bytes 
  466.  
  467.  
  468. // Writing definition of field name to dbase file header.
  469.       memset(bufje,0,11);
  470.       strcpy(bufje,"NAME");
  471.       fwrite(bufje,11,1,fo);
  472.       fputc('C',fo); 
  473.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  474.       fputc(40,fo); 
  475.       fputc(0,fo); 
  476.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  477.  
  478. // Writing definition of field adre to dbase file header.
  479.       memset(bufje,0,11);
  480.       strcpy(bufje,"ADRE");
  481.       fwrite(bufje,11,1,fo);
  482.       fputc('C',fo); 
  483.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  484.       fputc(32,fo); 
  485.       fputc(0,fo); 
  486.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  487.  
  488. // Writing definition of field city to dbase file header.
  489.       memset(bufje,0,11);
  490.       strcpy(bufje,"CITY");
  491.       fwrite(bufje,11,1,fo);
  492.       fputc('C',fo); 
  493.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  494.       fputc(23,fo); 
  495.       fputc(0,fo); 
  496.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  497.  
  498. // Writing definition of field count to dbase file header.
  499.       memset(bufje,0,11);
  500.       strcpy(bufje,"COUNT");
  501.       fwrite(bufje,11,1,fo);
  502.       fputc('C',fo); 
  503.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  504.       fputc(32,fo); 
  505.       fputc(0,fo); 
  506.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  507.  
  508. // Writing definition of field zip to dbase file header.
  509.       memset(bufje,0,11);
  510.       strcpy(bufje,"ZIP");
  511.       fwrite(bufje,11,1,fo);
  512.       fputc('C',fo); 
  513.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  514.       fputc(9,fo); 
  515.       fputc(0,fo); 
  516.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  517.  
  518. // Writing definition of field tel to dbase file header.
  519.       memset(bufje,0,11);
  520.       strcpy(bufje,"TEL");
  521.       fwrite(bufje,11,1,fo);
  522.       fputc('C',fo); 
  523.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  524.       fputc(17,fo); 
  525.       fputc(0,fo); 
  526.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  527.  
  528. // Writing definition of field update to dbase file header.
  529.       memset(bufje,0,11);
  530.       strcpy(bufje,"UPDATE");
  531.       fwrite(bufje,11,1,fo);
  532.       fputc('D',fo); 
  533.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  534.       fputc(8,fo); 
  535.       fputc(0,fo); 
  536.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  537.  
  538. // Writing definition of field birth to dbase file header.
  539.       memset(bufje,0,11);
  540.       strcpy(bufje,"BIRTH");
  541.       fwrite(bufje,11,1,fo);
  542.       fputc('D',fo); 
  543.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  544.       fputc(8,fo); 
  545.       fputc(0,fo); 
  546.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  547.  
  548. // Writing definition of field relation to dbase file header.
  549.       memset(bufje,0,11);
  550.       strcpy(bufje,"RELATION");
  551.       fwrite(bufje,11,1,fo);
  552.       fputc('C',fo); 
  553.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  554.       fputc(10,fo); 
  555.       fputc(0,fo); 
  556.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  557.  
  558. // Writing definition of field info to dbase file header.
  559.       memset(bufje,0,11);
  560.       strcpy(bufje,"INFO");
  561.       fwrite(bufje,11,1,fo);
  562.       fputc('C',fo); 
  563.       for(i=0;i<4;i++) fputc(0,fo); // 4 dummy bytes 
  564.       fputc(70,fo); 
  565.       fputc(0,fo); 
  566.       for(i=0;i<14;i++) fputc(0,fo); // 14 dummy bytes 
  567.  
  568.  
  569.       fputc(13,fo);  //Field terminator 
  570.       fputc(0,fo); 
  571.  
  572. // By now we have written the definition of the file structure 
  573. // to the file header. 
  574. // From here on we will export the records. 
  575.  
  576.      record *recp;
  577.      for(long l=numrec();l>0;l--) 
  578.      {
  579.  
  580.         if(ferror(fo)) { fclose(fo); return FALSE; } 
  581.         recp=(record *)db.locate_rec(l);
  582.  
  583.         if(db.is_delet(l)) fputc(42,fo); 
  584.         else               fputc(32,fo); 
  585.  
  586. /////////////////////// writing field name /////////////
  587.         fprintf(fo,"%-40s",recp->_name);
  588. /////////////////////// writing field adre /////////////
  589.         fprintf(fo,"%-32s",recp->_adre);
  590. /////////////////////// writing field city /////////////
  591.         fprintf(fo,"%-23s",recp->_city);
  592. /////////////////////// writing field count /////////////
  593.         fprintf(fo,"%-32s",recp->_count);
  594. /////////////////////// writing field zip /////////////
  595.         fprintf(fo,"%-9s",recp->_zip);
  596. /////////////////////// writing field tel /////////////
  597.         fprintf(fo,"%-17s",recp->_tel);
  598. /////////////////////// writing field update /////////////
  599.         if(recp->__update)
  600.         { 
  601.           d_upda.sem_jul(recp->__update);
  602.           fprintf(fo,"%4d",d_upda.year4());
  603.           fprintf(fo,"%02d",d_upda.month());
  604.           fprintf(fo,"%02d",d_upda.day());
  605.         } 
  606.         else 
  607.         { 
  608.           fprintf(fo,"        "); 
  609.         } 
  610. /////////////////////// writing field birth /////////////
  611.         if(recp->__birth)
  612.         { 
  613.           d_upda.sem_jul(recp->__birth);
  614.           fprintf(fo,"%4d",d_upda.year4());
  615.           fprintf(fo,"%02d",d_upda.month());
  616.           fprintf(fo,"%02d",d_upda.day());
  617.         } 
  618.         else 
  619.         { 
  620.           fprintf(fo,"        "); 
  621.         } 
  622. /////////////////////// writing field relation /////////////
  623.         fprintf(fo,"%-10s",recp->_relation);
  624. /////////////////////// writing field info /////////////
  625.         fprintf(fo,"%-70s",recp->_info);
  626.      }
  627.      fputc(26,fo);  //End of File 
  628.      fclose(fo); 
  629.  
  630.  return TRUE; 
  631. }
  632.  
  633. ///////////////////////////////// tokenize field ///////////////////////
  634. void NAM_foundation::tokenize(char *s,void(NAM_foundation::*fun)(void *))
  635. {
  636.  
  637.      char delim[]="\t,() "; //Token delimiters
  638.      char *p,*q=s;
  639.      char c;
  640.      int  insert=FALSE;
  641.      const min_len=4;  //Minimum length for a token to be indexed.
  642.  
  643.      p=strpbrk(q,delim);
  644.      while(p)
  645.      {
  646.         c=*p; *p=0;
  647.         if(strlen(q)>=min_len) { (this->*fun)(q); insert=TRUE; }
  648.         *p=c;
  649.         do{ p=strpbrk(q=p+1,delim); }while(q==p);
  650.      }
  651.  
  652.      if(strlen(q)>=min_len) { (this->*fun)(q); insert=TRUE; }
  653.      if(!insert) (this->*fun)(s);
  654.  
  655. }